package com.turing.post.datatranfer.impl;

import java.math.BigInteger;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;

import com.turing.post.account.util.AccountSystemAddTradDetail;
import com.turing.post.account.util.AccountSystemAddTradDetailDao;
import com.turing.post.account.util.AccountSystemTradDetail;
import com.turing.post.account.util.AccountSystemTradDetailDao;
import com.turing.post.account.util.MasterAccount;
import com.turing.post.account.util.MasterAccountDao;
import com.turing.post.account.util.SubAccount;
import com.turing.post.account.util.SubAccountDao;
import com.turing.post.account.util.SubAccountDetail;
import com.turing.post.account.util.SubAccountDetailDao;
import com.turing.post.cardmanagement.util.CardFace;
import com.turing.post.cardmanagement.util.CardFaceDao;
import com.turing.post.cardmanagement.util.CardStock;
import com.turing.post.cardmanagement.util.CardStockDao;
import com.turing.post.common.util.PCPSCommonDao;
import com.turing.post.datatranfer.util.ActivateCard;
import com.turing.post.datatranfer.util.ActivateCardBusiness;
import com.turing.post.datatranfer.util.CardControl;
import com.turing.post.datatranfer.util.CardControlDao;
import com.turing.post.organization.util.IssueCompany;
import com.turing.post.organization.util.IssueCompanyDao;
import com.turing.post.thirdinterface.util.MapCardClassic;
import com.turing.post.thirdinterface.util.MapCardClassicDao;
import com.turing.post.thirdinterface.util.MapSaleBranchDao;
import com.turing.post.thirdinterface.util.ThirdInterfaceRespCode;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;

/**
 * 激活卡业务接口实现
 * 
 * @author kangzhe
 * 
 */
@Stateless(mappedName = "datatranfer.impl.ActivateCardBusinessImpl")
@Remote
@Local
public class ActivateCardBusinessImpl implements ActivateCardBusiness {

	@EJB(mappedName = "datatranfer.impl.ActivateCardBusinessImpl")
	private ActivateCardBusiness activateCardBusinessImpl;

	// 数据迁移接口实现对象(card)
	@EJB(mappedName = "datatranfer.impl.ActivateCardDaoImpl")
	private com.turing.post.datatranfer.util.ActivateCardDao cardAccDao;

	@EJB(mappedName = "datatranfer.impl.CardControlDaoImpl")
	private CardControlDao ccDao;

	@EJB(mappedName = "thirdinterface.impl.MapSaleBranchDaoImpl")
	private MapSaleBranchDao mapSaleBrchDao;

	@EJB(mappedName = "thirdinterface.impl.MapCardClassicDaoImpl")
	private MapCardClassicDao mapCardClassicDao;

	// pcps接口实现对象
	@EJB(mappedName = "common.impl.PCPSCommonDaoImpl")
	private PCPSCommonDao pcpsCommonDaoImpl;

	@EJB(mappedName = "account.impl.MasterAccountDaoImpl")
	private MasterAccountDao maDao;

	@EJB(mappedName = "account.impl.SubAccountDaoImpl")
	private SubAccountDao saDao;

	@EJB(mappedName = "cardmanagement.impl.ActivateCardDaoImpl")
	private com.turing.post.cardmanagement.util.ActivateCardDao pcpsAccDao;

	@EJB(mappedName = "account.impl.SubAccountDetailDaoImpl")
	private SubAccountDetailDao subAccDao;

	@EJB(mappedName = "cardmanagement.impl.CardFaceDaoImpl")
	private CardFaceDao cardFaceDao;

	@EJB(mappedName = "organization.impl.IssueCompanyDaoImpl")
	private IssueCompanyDao issueCompanyDao;

	@EJB(mappedName = "account.impl.AccountSystemTradDetailDaoImpl")
	private AccountSystemTradDetailDao accstdDao;

	@EJB(mappedName = "account.impl.AccountSystemAddTradDetailDaoImpl")
	private AccountSystemAddTradDetailDao accsatdDao;

	@EJB(mappedName = "cardmanagement.impl.CardStockDaoImpl")
	private CardStockDao cardStockDaoImpl;

	/**
	 * 异常抛出方法
	 * 
	 * @param error
	 * @throws PCPSApplicationException
	 */
	@SuppressWarnings("unused")
	private void errException(String error) throws PCPSApplicationException {
		throw new PCPSApplicationException(ThirdInterfaceRespCode.RC_PARAMETER,
				error);
	}

	@Override
	public void tranferActivateCard(String issueCompanyNo, String batchNo)
			throws PCPSApplicationException {
		// 根据批次号获取激活卡总数(新系统)
		int newCardCount = pcpsAccDao
				.getActivateCardTotalCountByBatchNo(batchNo);
		// 根据批次号获取激活卡总数(旧系统)
		int cardCount = cardAccDao.getOldActivateCardTotalCount(batchNo);
		if (newCardCount == cardCount) {
			System.out.println("批次号:" + batchNo + "已经迁移完!");
			return;
		}

		String cardSeqNo = "";
		com.turing.post.datatranfer.util.ActivateCard ac = null;
		IssueCompany issueCompany = issueCompanyDao
				.getIssueCompanyByIssueCompanyNo(issueCompanyNo);
		// 销售机构
		Map<BigInteger, String> saleBranchMap = new HashMap<BigInteger, String>();
		// 老系统卡控制表的卡面值
		Map<String, BigInteger> cardControlMap = new HashMap<String, BigInteger>();
		// 卡种类map
		Map<String, BigInteger> cardClassicMap = new HashMap<String, BigInteger>();

		String saleBrchNo = "";
		BigInteger cardParVal = null;
		CardControl ccobj = null;
		BigInteger cardClassicId = null;
		MapCardClassic mapCardClassic = null;

		// 取卡面信息
		List<CardFace> cardFaceList = cardFaceDao
				.getAllCardFaceByIssueCompanyNo(issueCompany
						.getIssueCompanyNo());
		if (cardFaceList == null || cardFaceList.size() <= 0) {
			return;
		}
		BigInteger cardFaceId = cardFaceList.get(0).getCardFaceId();
		// 循环加载,最大为TranferConfig.PAGE

		List<ActivateCard> list = cardAccDao
				.getOldActivateCardByBatchNo(batchNo);
		for (int i = 0; i < cardCount; i++) {
			/**
			 * 1.初始化获取老系统卡序号
			 */
			cardSeqNo = list.get(i).getCardSeqNo();
			// 如果新系统中存在激活卡cardSeqNo,则进行下一条
			if (null != pcpsAccDao.getActivateCardByCardSeqNo(cardSeqNo)) {
				continue;
			}
			ac = cardAccDao.getOldActivateCardBySeqNo(cardSeqNo);
			/**
			 * 2.判断销售机构合法性
			 */
			if (saleBranchMap.get(ac.getCustomId()) == null
					|| saleBrchNo == null) {
				saleBrchNo = mapSaleBrchDao.getSaleBrchNoFromMapSaleBranch(ac
						.getCustomId());
				saleBranchMap.put(ac.getCustomId(), saleBrchNo);
			} else {
				saleBrchNo = saleBranchMap.get(ac.getCustomId());
			}

			/**
			 * 3.检查卡面值合法性
			 */
			if (cardControlMap.get(ac.getBatchNo()) == null
					|| cardParVal == null) {
				ccobj = ccDao.getCardControlByBatchNo(ac.getBatchNo());
				cardControlMap.put(ac.getBatchNo(), new BigInteger(ccobj
						.getCardParValue().toString()));
			} else {
				cardParVal = cardControlMap.get(ac.getBatchNo());
			}

			/**
			 * 4. 检查卡种类合法性
			 */
			if (cardClassicMap.get(ccobj.getCardKindId()) == null
					|| cardClassicId == null) {
				mapCardClassic = mapCardClassicDao
						.getMapCardClassicByBindingTypeNo(ccobj.getCardKindId());
				cardClassicMap.put(ccobj.getCardKindId(), mapCardClassic
						.getCardClassicId());
				cardClassicId = mapCardClassic.getCardClassicId();
			} else {
				cardClassicId = cardClassicMap.get(ccobj.getCardKindId());
			}

			/**
			 * 5. 插入迁移数据
			 */
			activateCardBusinessImpl.insertTranferInfos(issueCompany,
					cardSeqNo, ac, cardFaceId, saleBrchNo, cardClassicId,
					cardParVal);
		}
	}

	/**
	 * 迁移单张卡数据
	 * 
	 * @param issueCompany
	 * @param cardSeqNo
	 * @param ac
	 * @param cardFaceId
	 * @param saleBranchNo
	 * @param cardClassicId
	 * @param cardParVal
	 * @throws PCPSApplicationException
	 */
	@TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRES_NEW)
	public void insertTranferInfos(IssueCompany issueCompany, String cardSeqNo,
			com.turing.post.datatranfer.util.ActivateCard ac,
			BigInteger cardFaceId, String saleBranchNo,
			BigInteger cardClassicId, BigInteger cardParVal)
			throws PCPSApplicationException {
		try {
			Date nowDateTime = pcpsCommonDaoImpl.getDatabaseSysTime();

			/**
			 * 1.在新数据库中MasterAccount表插入一条记录,卡号为Null.主账号自动生成.
			 */
			// 设置记表参数
			MasterAccount mac = new MasterAccount();
			BigInteger masterAccNo = pcpsCommonDaoImpl.getUniqueIntegerKey();
			mac.setMasterAccNo(masterAccNo);
			mac.setIssueCompanyNo(issueCompany.getIssueCompanyNo());
			mac.setCardNo(ac.getCardNo());
			mac.setOwnerId(null);
			mac.setBalance(ac.getBalance());
			mac.setOpenTime(nowDateTime);
			mac.setOpenStatus(MasterAccount.MASTERACCOUNT_OPENSTATUS_NORMAL);
			mac.setCloseStatus(MasterAccount.MASTERACCOUNT_CLOSESTATUS_NONE);
			mac.setFreeze(MasterAccount.MASTERACCOUNT_FREEZE_NONE);
			mac.setFreezeAmount(BigInteger.ZERO);
			mac.setStopPayment(MasterAccount.MASTERACCOUNT_STOPPAYMENT_NONE);
			mac.setAuthDeposit(BigInteger.ZERO);
			mac.setAuthRedemp(BigInteger.ZERO);
			mac.setLastAccountTime(nowDateTime);
			mac.setRemark("旧数据迁入");
			maDao.insert(mac);

			/**
			 * 2.在新数据库SubAccount表中插入一条记录.关联主账号为3步骤产生的
			 */
			SubAccount sac = new SubAccount();
			// 设置记表参数
			BigInteger subAccNo = pcpsCommonDaoImpl.getUniqueIntegerKey();
			sac.setSubAccNo(subAccNo);
			sac.setMasterAccNo(masterAccNo);
			sac.setOpenBranchNo(saleBranchNo);
			sac.setOpenTime(nowDateTime);
			sac.setLastAccountTime(nowDateTime);
			sac.setSalesGroupId(null);
			sac.setBalance(ac.getBalance());
			sac.setAppId(null);
			sac.setAppSeqNo(null);
			saDao.insert(sac);

			/**
			 * 3.在新数据库ActivateCard表中插入一条记录,将主账号填为3步骤产生的,
			 * 并将3步骤的主账户记录中的cardno设置为cardno.
			 */
			com.turing.post.cardmanagement.util.ActivateCard acobj = new com.turing.post.cardmanagement.util.ActivateCard();
			acobj
					.setBatchNo(issueCompany.getIssueCompanyNo()
							+ ac.getBatchNo());
			acobj.setCardSeqNo(ac.getCardSeqNo());
			acobj.setCardNo(ac.getCardNo());
			acobj.setCardClassicId(cardClassicId);
			acobj.setCardFaceId(cardFaceId);
			acobj.setMasterAccNo(masterAccNo);
			acobj.setWalletAccNo(null);
			acobj.setCardPwd(ac.getCardPwd());
			acobj.setTwoTrackContent(ac.getCardNo());
			acobj.setThirdTrackContent(ac.getCardNo());
			acobj.setSaleBranchNo(saleBranchNo);
			acobj.setOpenBranchNo(saleBranchNo);
			acobj.setSaleOrderId(null);
			acobj.setBuyerId(null);
			acobj.setOwnerId(null);
			acobj.setInitialBalance(cardParVal);
			acobj.setTotalDeposit(BigInteger.ZERO);
			acobj.setBalance(ac.getBalance());
			acobj.setWalletBalance(BigInteger.ZERO);
			acobj.setExpired(ac.getExpired());
			acobj.setLastExpiredFeeDate(null);
			acobj.setPwdErrCnt(ac.getPwdErrCnt());
			acobj.setLastPwdErrTime(ac.getLastPwdErrTime());
			acobj.setOpenTime(nowDateTime);
			acobj.setOpenStatus("0");
			acobj.setCloseStatus("0");
			acobj.setLastLossTime(null);
			acobj.setLossStatus("0");
			acobj.setManualLockStatus("0");
			acobj.setActivateMac(null);
			acobj.setTotalConsumeCount(BigInteger.ZERO);
			acobj.setOrigCardNo(null);
			acobj.setNewCardNo(null);
			pcpsAccDao.insert(acobj);

			/**
			 * 4.将本事务使用的旧系统卡顺序号(seqNo)记录到已迁移激活卡中(MapActivatecard)
			 */
			// mapAcvCardDao.insertOldActivateCardSeqNoToMap(cardSeqNo);
			/**
			 * 5. 如果老卡号上面余额大于0
			 */
			if (ac.getBalance().compareTo(BigInteger.ZERO) > 0) {
				// 帐户子系统流水号
				String accSeqNo = generateAccSeqNo(issueCompany
						.getIssueCompanyNo(), nowDateTime);
				/**
				 * a.记子帐户明细（SubAccountDetail）
				 */
				SubAccountDetail subAccDetailObj = new SubAccountDetail();
				subAccDetailObj.setSubAccNo(subAccNo);
				subAccDetailObj.setTranDate(issueCompany.getTranDate());
				subAccDetailObj.setTranTime(nowDateTime);
				subAccDetailObj.setAccSeqNo(accSeqNo);
				subAccDetailObj.setAccSubSeqNo(0);
				subAccDetailObj.setDebitAmount(BigInteger.ZERO);
				subAccDetailObj.setCreditAmount(ac.getBalance());
				subAccDetailObj.setBalance(ac.getBalance());
				subAccDetailObj.setSummary("数据迁移");
				subAccDao.insert(subAccDetailObj);

				/**
				 * b.记帐户子系统交易流水（AccountSystemTradDetail）
				 */
				AccountSystemTradDetail accstd = new AccountSystemTradDetail();
				accstd.setAccSeqNo(accSeqNo);
				accstd.setTranDate(issueCompany.getTranDate());
				accstd.setIssueCompanyNo(issueCompany.getIssueCompanyNo());
				accstd.setTranTime(nowDateTime);
				accstd.setTranSeqNo("datatranfer...");
				accstd.setDebitAmount(BigInteger.ZERO);
				accstd.setCreditAmount(ac.getBalance());
				accstd.setCancelAccSeqNo(null);
				accstd.setCancelTranDate(null);
				accstd.setCancelTranSeqNo(null);
				accstd.setOperId(null);
				accstd.setSummary("数据迁移");
				accstdDao.insert(accstd);

				/**
				 * c.帐户子系统交易附加流水（AccountSystemAddTradDetail）
				 */
				AccountSystemAddTradDetail asatd = new AccountSystemAddTradDetail();
				asatd.setAccSeqNo(accSeqNo);
				asatd.setAccSubSeqNo(0);
				asatd.setIssueCompanyNo(issueCompany.getIssueCompanyNo());
				asatd.setTranDate(issueCompany.getTranDate());
				asatd.setTranTime(nowDateTime);
				asatd.setMasterAccNo(masterAccNo);
				asatd.setCardNo(ac.getCardNo());
				asatd.setCardClassicId(cardClassicId);
				asatd.setSubAccNo(subAccNo);
				asatd.setOpenBranchNo(saleBranchNo);
				asatd.setTranType(AccountSystemAddTradDetail.TRANTYPE_OPEN);
				asatd.setDebitAmount(BigInteger.ZERO);
				asatd.setCreditAmount(ac.getBalance());
				asatd.setBalance(ac.getBalance());
				asatd.setMasBalance(ac.getBalance());
				asatd.setRemark("数据迁移");
				accsatdDao.insert(asatd);
			}
		} catch (Exception e) {
			System.out.println("***事务发生异常***卡序号为:" + cardSeqNo);
		}
	}

	/**
	 * 产生帐户子系统交易/特殊流水号
	 * 
	 * @param issueCompanyNo
	 * @param tranTime
	 * @return
	 */
	private String generateSeqNo(String issueCompanyNo, Date tranTime,
			String category) {
		BigInteger seqno = pcpsCommonDaoImpl.getAccountSubSystemSeqNo();
		seqno = seqno.mod(BigInteger.valueOf(1000000));

		return issueCompanyNo + category
				+ PCPSUtil.getStringYMDHMSPackedByDate(tranTime)
				+ String.format("%06d", seqno);
	}

	/**
	 * 产生帐户子系统交易流水号
	 * 
	 * @param issueCompanyNo
	 * @param tranTime
	 * @return
	 */
	private String generateAccSeqNo(String issueCompanyNo, Date tranTime) {
		return generateSeqNo(issueCompanyNo, tranTime, "ACC");
	}

	/**
	 * ---激活卡迁移数据移除 ---1.清空pcpsDB中的已迁移子系统附加交易流水 delete from
	 * accountsystemaddtraddetail t where t.remark = '数据迁移';
	 * ---2.清空pcpsDB中的已迁移子系统交易流水 delete from accountsystemtraddetail t where
	 * t.summary = '数据迁移'; ---3.清空pcpsDB中的已迁移子账户明细 delete from subaccountdetail
	 * t where t.summary = '数据迁移'; ---4.清空pcpsDB中的已迁移子账户 delete subaccount a
	 * where exists(select b.masteraccno from masteraccount b where
	 * b.masteraccno=a.masteraccno and length(b.cardno)=16) ---5.清空pcpsDB中的已迁主账户
	 * delete from masteraccount t where length(t.cardno)=16;
	 * ---6.清空pcpsDB中的已迁移激活卡 delete from from activatecard t where
	 * length(t.cardseqno)=12; ---7.清空激活卡map表 delete from mapactivatecard t;
	 */

	@Override
	public void insertSaleCard(String issueCompanyNo, String cardSeqNo,
			BigInteger cardFaceId, String saleBranchNo, BigInteger cardParVal,
			BigInteger cardClassicId) throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(issueCompanyNo)) {
			PCPSUtil
					.Log("com.turing.post.datatranfer.impl.insertSaleCard:插入失败,发卡机构号不能为空!");
			throw new PCPSApplicationException("", "", "");
		}
		if (PCPSUtil.isEmpty(cardSeqNo)) {
			PCPSUtil
					.Log("com.turing.post.datatranfer.impl.insertSaleCard:插入失败,卡序号不能为空!");
			throw new PCPSApplicationException("", "", "");
		}
		if (cardFaceId == null) {
			PCPSUtil
					.Log("com.turing.post.datatranfer.impl.insertSaleCard:插入失败,卡面编号不能为空!");
			throw new PCPSApplicationException("", "", "");
		}
		if (PCPSUtil.isEmpty(saleBranchNo)) {
			PCPSUtil
					.Log("com.turing.post.datatranfer.impl.insertSaleCard:插入失败,销售机构号不能为空!");
			throw new PCPSApplicationException("", "", "");
		}
		if (cardParVal == null) {
			PCPSUtil
					.Log("com.turing.post.datatranfer.impl.insertSaleCard:插入失败,卡面值不能为空!");
			throw new PCPSApplicationException("", "", "");
		}
		if (cardClassicId == null) {
			PCPSUtil
					.Log("com.turing.post.datatranfer.impl.insertSaleCard:插入失败,卡种类不能为空!");
			throw new PCPSApplicationException("", "", "");
		}

		IssueCompany issueCompany = issueCompanyDao
				.getIssueCompanyByIssueCompanyNo(issueCompanyNo);
		if (issueCompany == null) {
			PCPSUtil
					.Log("com.turing.post.datatranfer.impl.insertSaleCard:插入失败,没有找到发卡商信息:"
							+ issueCompanyNo + "!");
			throw new PCPSApplicationException("", "", "");
		}
		ActivateCard ac = new ActivateCard();
		CardStock cs = cardStockDaoImpl.getCardStockByCardseqno(cardSeqNo);
		if (cs == null) {
			PCPSUtil
					.Log("com.turing.post.datatranfer.impl.insertSaleCard:插入失败,卡库存中没有找到此卡序号:"
							+ cardSeqNo + "!");
			throw new PCPSApplicationException("", "", "");
		}
		ac.setCardNo(cs.getCardNo());
		ac.setCardSeqNo(cs.getCardSeqNo());
		ac.setBalance(cardParVal);
		ac.setBatchNo(cs.getBatchNo().substring(6));
		ac.setCardPwd(cs.getCardPwd());
		ac.setExpired(PCPSUtil.getDateYMDByString("2015-12-31"));
		ac.setPwdErrCnt(0);
		ac.setLastPwdErrTime(null);
		/**
		 * 插入激活卡
		 */
		activateCardBusinessImpl.insertTranferInfos(issueCompany, cardSeqNo,
				ac, cardFaceId, saleBranchNo, cardClassicId, cardParVal);
	}
}
